package com.example.game.hff;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.sound.sampled.Clip;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * 게임의 내용이 출력되는 화면 클래스
 * 
 * @author Administrator
 * 
 */

public class MainScreen extends JPanel implements Runnable, Constants {

	//각 게임 객체들이 사용할 이미지 변수
	private Image playerImage;
	private Image backgroundImage;
	private Image busImage;
	private Image busToRightImage;
	private Image ambulanceImage;
	private Image armyImage;
	private Image itemImage;
	private Image item2Image;
	private Image endGameImage;
	private Image mainMenuImage;
	private Image skillEffectImage;
	private Image skill2EffectImage;
	private Image crashImage;
	
	private Rectangle playerRect = new Rectangle();
	private Rectangle busRect = new Rectangle();
	private Rectangle busToRightRect = new Rectangle();
	private Rectangle ambulanceRect = new Rectangle();
	private Rectangle armyRect = new Rectangle();
	private Rectangle itemRect = new Rectangle();
	private Rectangle item2Rect = new Rectangle();
	
	private PlayerHp playerHp;
	private Skill skill;
	private Player player;
	private Background background;
	private Item item;
	private Item2 item2;
	private EndGame endGame;
	private MainMenu mainMenu;
	
	private LinkedList<SkillEffect> skillEffects;
	private LinkedList<Skill2Effect> skill2Effects;
	private LinkedList<Bus> buses;
	private LinkedList<BusToRight> busToRight;
	private LinkedList<Ambulance> ambulances;
	private LinkedList<Army> armies;
	private LinkedList<Item2> items2;
	private LinkedList<Crash> crashes;
	
	//차량이 생성된 후 다음 번 장애물을 생성할 때 까지의 최소 시간
	private int carInterval = 1500;
	private int item2Interval = 15000;
	private int soundInterval = 2000;
	private int mainSoundInterval = 167000;
	
	//마지막으로 차량이 생성된 시간
	private long lastCarCreationTime;
	private long item2CreationTime;
	private long soundPlayingTime;
	private long mainSoundPlayingTime;
	
	//글자를 표시(drawString)할 때 사용할 폰트 변수
	private Font font;
	private boolean running, gameover;
	private int score = 0;
	private RankDao dao;
	private String playName = "";
	private List<Rank> ranks;

	public MainScreen() {
		try{
			Class.forName("com.mysql.jdbc.Driver");
		//	Class.forName("org.apache.commons.dbcp.PoolingDriver");
		}catch(Exception ex){
			ex.printStackTrace();
		}
		dao = new RankDao();
		try {
			URL url = getClass().getResource("/hff_background2.png");
			Image originalImage = ImageIO.read(url);
			backgroundImage = originalImage.getScaledInstance(1200, 800,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/dog4.png");
			originalImage = ImageIO.read(url);
			playerImage = originalImage;
			
								
			url = getClass().getResource("/bus22.png");
			originalImage = ImageIO.read(url);
			busImage = originalImage.getScaledInstance(256, 100,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/busToRight.png");
			originalImage = ImageIO.read(url);
			busToRightImage = originalImage.getScaledInstance(256, 100,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/ambulance.png");
			originalImage = ImageIO.read(url);
			ambulanceImage = originalImage.getScaledInstance(192, 100,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/army.png");
			originalImage = ImageIO.read(url);
			armyImage = originalImage.getScaledInstance(192, 100,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/meat22.png");
			originalImage = ImageIO.read(url);
			itemImage = originalImage.getScaledInstance(96, 64,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/DogHazard.png");
			originalImage = ImageIO.read(url);
			item2Image = originalImage.getScaledInstance(64, 64,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/busover2.png");
			originalImage = ImageIO.read(url);
			endGameImage = originalImage.getScaledInstance(1200, 800,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/hfdmain2.png");
			originalImage = ImageIO.read(url);
			mainMenuImage = originalImage.getScaledInstance(1200, 800 ,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/superdog3.png");
			originalImage = ImageIO.read(url);
			skillEffectImage = originalImage.getScaledInstance(800, 800 ,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/superdog44.png");
			originalImage = ImageIO.read(url);
			skill2EffectImage = originalImage.getScaledInstance(800, 800 ,
					Image.SCALE_SMOOTH);
			
			url = getClass().getResource("/bom.png");
			originalImage = ImageIO.read(url);
			crashImage = originalImage.getScaledInstance(192, 128,
					Image.SCALE_SMOOTH);
			
	
		} catch (Exception ex) {
		}
		background = new Background(backgroundImage);
		player = new Player(playerImage, 4);
		playerHp = new PlayerHp();
		item = new Item(itemImage);
		endGame = new EndGame(endGameImage);
		mainMenu = new MainMenu(mainMenuImage);
		skill = new Skill();
		
		skillEffects = new LinkedList<SkillEffect>();
		skill2Effects = new LinkedList<Skill2Effect>();
		buses = new LinkedList<Bus>();
		busToRight = new LinkedList<BusToRight>();
		ambulances = new LinkedList<Ambulance>();
		armies = new LinkedList<Army>();
		items2 = new LinkedList<Item2>();
		crashes = new LinkedList<Crash>();
		
		setDoubleBuffered(true); //출력의 효율을 위한
		addKeyListener(keyListener);


				
	}
	
	private void startGame() {
		playName = JOptionPane.showInputDialog("이름을 입력하세요.");
		Sound.stop2();
		Sound.play2("Sonic");
		Sound.loop2();
		
		

		score = 0;
		playerHp.currentHp = 3;
		player.skillPoint = 2;
		
		player.setX(560);
		player.setY(730);
		
		lastCarCreationTime = System.currentTimeMillis()-2000;
		item2CreationTime= System.currentTimeMillis()+500;
		soundPlayingTime = System.currentTimeMillis();
		
		running = false;
		gameover = false;
		
		Thread thread = new Thread(this);
		thread.start();
		
	}
	
	private Font myFont = new Font("Verdana", Font.BOLD, 40);
	private Font myFont2 = new Font("굴림", Font.BOLD, 40);
	
	@Override
	public void paint(final Graphics g) {
		super.paint(g);
		
		Image image = this.createImage(
			(int)getPreferredSize().getWidth(), (int)getPreferredSize().getHeight());
		
		Graphics temp = image.getGraphics();
				
		if (!running && !gameover) {
			mainMenu.draw(temp);
			g.drawImage(image, 0, 0, null);
			repaint();
			return;
		}
		
		if (gameover == true) {			
			endGame.draw(temp);
			g.drawImage(image, 0, 0, null);
			gameoverDraw(g);
			repaint();
			return;
		}

		
			background.draw(temp);
			player.draw(temp);
			item.draw(temp);	
			playerHp.draw(temp);
			skill.draw(temp);
			//repaint();
			
			for (SkillEffect skillEffect : skillEffects) {
				skillEffect.draw(temp);
			}
			
			for (Skill2Effect skill2Effect : skill2Effects) {
				skill2Effect.draw(temp);
			}
			
			for (Bus bus : buses) {
				bus.draw(temp);
			}
			
			for (BusToRight busR : busToRight) {
				busR.draw(temp);
			}
			
			for (Ambulance ambulance : ambulances) {
				ambulance.draw(temp);
			}
			
			for (Army army : armies) {
				army.draw(temp);
			}
			
			for(Item2 item2 : items2){
				item2.draw(temp);
			}
			
			for (Crash crash : crashes) {
				crash.draw(temp);
			}					
					temp.setFont(myFont);
					temp.setColor(Color.BLACK);
					temp.drawString(String.format("SCORE : %d", score),10,40);
					temp.drawString(String.format("HP : "), 350, 40);
					temp.drawString(String.format("SP : "), 600, 40);
			
					
					g.drawImage(image, 0, 0, null);
		}
		
//	}
	private void gameoverDraw(Graphics g){
		   ranks = dao.getRankByScore();//ASC:오름차순,DESC:내림차순
		   setFont(myFont2);
		   setBackground(Color.white);
		   g.drawString(ranks.get(0).getName(), 500, 180);
		   g.drawString(String.valueOf(ranks.get(0).getScore()), 700, 180 );
		   g.drawString(ranks.get(1).getName(), 500, 244);
		   g.drawString(String.valueOf(ranks.get(1).getScore()), 700, 244);
		   g.drawString(ranks.get(2).getName(), 500, 305);
		   g.drawString(String.valueOf(ranks.get(2).getScore()), 700, 305);
		  }
 
	@Override
	public void run() {
		running = true;
		
		loop : while (running) {
			// Hp가 0일때 running stop
			
			playerRect.x = player.getX() + 25;
			playerRect.y = player.getY() + 15;
			playerRect.width = player.getWidth() - 25;
			playerRect.height = player.getHeight() - 15;
			
			//차량별 충돌 체크
			//1. 왼쪽으로 가는 버스 충돌
			for (int i = 0; i < buses.size(); i++) {
				Bus bus = buses.get(i);
				busRect.x = bus.getX() + 25;
				busRect.y = bus.getY() + 15;
				busRect.width = bus.getWidth() - 25;
				busRect.height = bus.getHeight() - 15;
			
				if (playerRect.intersects(busRect)) {					
					Sound.play2("horn");
					bus.setActive(false);
					playerHp.currentHp --;
					crashes.add(new Crash(crashImage, player.getX(), player.getY()));
					repaint();
					
					if (playerHp.currentHp == 0) {
						gameover = true;
						ambulances.removeAll(ambulances);
						armies.removeAll(armies);
						buses.removeAll(buses);
						busToRight.removeAll(busToRight);
						items2.removeAll(items2);
						Sound.stop();
						repaint();
						running = false;
						Rank rank = new Rank(playName, score);
						dao.insertRank(rank);						
						Sound.play2("hohohaha");
						
								
					}
				}
			}
			// 2. 오른쪽으로 가는 버스 충돌
			for (int i = 0; i < busToRight.size(); i++) {
				BusToRight busR = busToRight.get(i);
				busToRightRect.x = busR.getX() + 25;
				busToRightRect.y = busR.getY() + 15;
				busToRightRect.width = busR.getWidth() - 25;
				busToRightRect.height = busR.getHeight() - 15;
				
				if (playerRect.intersects(busToRightRect)) {
					Sound.play2("horn");
					busR.setActive(false);
					playerHp.currentHp --;
					crashes.add(new Crash(crashImage, player.getX(), player.getY()));
					repaint();
					if (playerHp.currentHp == 0) {
						gameover = true;
						ambulances.removeAll(ambulances);
						armies.removeAll(armies);
						buses.removeAll(buses);
						busToRight.removeAll(busToRight);
						items2.removeAll(items2);
						Sound.stop();
						repaint();
						running = false;
						Rank rank = new Rank(playName, score);
						dao.insertRank(rank);
						Sound.play2("hohohaha");
						
								
					}
				}
			}
			// 3. 왼쪽으로 가는 구급차 충돌
			for (int i = 0; i < ambulances.size(); i++) {
				Ambulance ambul = ambulances.get(i);
				ambulanceRect.x = ambul.getX() + 25;
				ambulanceRect.y = ambul.getY() + 15;
				ambulanceRect.width = ambul.getWidth() - 25;
				ambulanceRect.height = ambul.getHeight() - 15;

				if (playerRect.intersects(ambulanceRect)) {
					Sound.play2("brake");
					ambul.setActive(false);
					playerHp.currentHp --;
					crashes.add(new Crash(crashImage, player.getX(), player.getY()));
					repaint();
					if (playerHp.currentHp == 0) {
						gameover = true;
						ambulances.removeAll(ambulances);
						armies.removeAll(armies);
						buses.removeAll(buses);
						busToRight.removeAll(busToRight);
						items2.removeAll(items2);
						Sound.stop();
						repaint();
						running = false;
						Rank rank = new Rank(playName, score);
						dao.insertRank(rank);
						Sound.play2("hohohaha");
						
								
					}
				}
			}
			//4. 오른쪽으로 가는 군용차 충돌
			for (int i = 0; i < armies.size(); i++) {
				Army armyCar = armies.get(i);
				armyRect.x = armyCar.getX() + 25;
				armyRect.y = armyCar.getY() + 15;
				armyRect.width = armyCar.getWidth() - 25;
				armyRect.height = armyCar.getHeight() - 15;
				
				if (playerRect.intersects(armyRect)) {
					Sound.play2("brake");
					armyCar.setActive(false);
					playerHp.currentHp --;
					crashes.add(new Crash(crashImage, player.getX(), player.getY()));
					repaint();
					if (playerHp.currentHp == 0) {
						gameover = true;
						ambulances.removeAll(ambulances);
						armies.removeAll(armies);
						buses.removeAll(buses);
						busToRight.removeAll(busToRight);
						items2.removeAll(items2);
						Sound.stop();
						repaint();
						running = false;
						Rank rank = new Rank(playName, score);
						dao.insertRank(rank);
						Sound.play2("hohohaha");
						
						
								
					}
				}
			}
			// 5. 아이템 충돌

			itemRect.x = item.getX();
			itemRect.y = item.getY();
			itemRect.width = item.getWidth();
			itemRect.height = item.getHeight();
					
			if (playerRect.intersects(itemRect)) {
				int h = (int)(Math.random() * 700) + 100;
				item.setX((int)(Math.random() * (SCREEN_WIDTH - item.getWidth())));
				item.setY(h - item.getHeight());
				Sound.play2("bikehorn");
				repaint();
				score += 10;
			}
			
			//2.아이템2 충돌 누리가.....
			for (int i = 0; i < items2.size(); i++) {
				Item2 item2 = items2.get(i);
				item2Rect.x = item2.getX();
				item2Rect.y = item2.getY();
				item2Rect.width = item2.getWidth();
				item2Rect.height = item2.getHeight();
						
				if (playerRect.intersects(item2Rect)) {
					items2.removeAll(items2);
					ambulances.removeAll(ambulances);
					armies.removeAll(armies);
					buses.removeAll(buses);
					busToRight.removeAll(busToRight);
					skillEffects.add(new SkillEffect(skillEffectImage));
					Sound.play2("howl");
					score += 50;
					repaint();
			
			   }
			}

				
		//update
		player.update();
		
		for (int i = skill2Effects.size() - 1; i >= 0; i--) {
			Skill2Effect skill2Effect = skill2Effects.get(i);
			skill2Effect.update();
			if (!skill2Effect.isActive()) {
				skillEffects.remove(skill2Effect);
			}
		}
		
		for (int i = skillEffects.size() - 1; i >= 0; i--) {
			SkillEffect skillEffect = skillEffects.get(i);
			skillEffect.update();
			if (!skillEffect.isActive()) {
				skillEffects.remove(skillEffect);
			}
		}
				
		for (int i = buses.size() - 1; i >= 0; i--) {
			Bus bus = buses.get(i);
			bus.update();
			if (!bus.isActive()) {
				buses.remove(bus);
			}
		}
		for (int i = busToRight.size() - 1; i >= 0; i--) {
			BusToRight busR = busToRight.get(i);
			busR.update();
			if (!busR.isActive()) {
				busToRight.remove(busR);
			}
		}
		for (int i = ambulances.size() - 1; i >= 0; i--) {
			Ambulance ambulance = ambulances.get(i);
			ambulance.update();
			if (!ambulance.isActive()) {
				ambulances.remove(ambulance);
			}
		}
		for (int i = armies.size() - 1; i >= 0; i--) {
			Army army = armies.get(i);
			army.update();
			if (!army.isActive()) {
				armies.remove(army);
			}
		}
		for (int i = items2.size() - 1; i >= 0; i--) {
			Item2 item2 = items2.get(i);
			item2.update();		
			if (!item2.isActive()) {
				items2.remove(item2);
			}
		}
		for (int i = crashes.size() - 1; i >= 0; i--) {
			Crash crash = crashes.get(i);
			if (!crash.isLive())
				crashes.remove(crash);
		}
		
		
		long currentTime = System.currentTimeMillis();
		if (currentTime - lastCarCreationTime > carInterval) {
			Bus bus = new Bus(busImage);
			buses.add(bus);
			
			BusToRight busR = new BusToRight(busToRightImage);
			busToRight.add(busR);
			
			Ambulance ambulance = new Ambulance(ambulanceImage);
			ambulances.add(ambulance);
			
			Army army = new Army(armyImage);
			armies.add(army);
			
			lastCarCreationTime = currentTime;
		
		}
		if (currentTime- item2CreationTime> item2Interval){
			 Item2 item2 = new Item2(item2Image);
			 items2.add(item2);
			
			 item2CreationTime = currentTime + 5000;
		}
		
		if (currentTime - soundPlayingTime > soundInterval){
			 
			 Sound.play2("race");
			 soundPlayingTime = currentTime + 5000;
		}
		
		
		
		
		
		
		repaint();
		
		
		try {
			Thread.sleep(25);
		} catch (Exception ex) {}
		}
		
	}

	private KeyListener keyListener = new KeyAdapter() {
		

		@Override
		public void keyPressed(KeyEvent e) {
			
			if (!running) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					startGame();
				}
			}

			if (running == true && player.skillPoint > 0) {

			if (e.getKeyCode() == KeyEvent.VK_SPACE) {
				skill2Effects.add(new Skill2Effect(skill2EffectImage));
				ambulances.removeAll(ambulances);
				armies.removeAll(armies);
				buses.removeAll(buses);
				busToRight.removeAll(busToRight);
				Sound.play2("bark");
			  }
			}
		
			player.keyPressedHandler(e);
			
			super.keyPressed(e);
		}
		

		public void keyReleased(KeyEvent e) {

			player.keyReleasedHandler(e);
			
			super.keyReleased(e);
		}
		
		  
	  };
	  
		

	
 }

  